#include "LZOCompressorHelper.h"
#include "lzo/lzoconf.h"
#include "LZOInclude\lzo\lzo1x.h"

using namespace WaveAccess::LZONet;

LZOCompressorHelper::LZOCompressorHelper()
{
	m_CompressFuncTable = gcnew Dictionary<CompressionAlgorithm, IntPtr>();
	m_DecompressFuncTable = gcnew Dictionary<CompressionAlgorithm, IntPtr>();
	m_DecompressSafeFuncTable = gcnew Dictionary<CompressionAlgorithm, IntPtr>();
	m_WorkMemorySizeTable = gcnew Dictionary<CompressionAlgorithm, lzo_uint32>();

	m_CompressFuncTable->Add(CompressionAlgorithm::LZO1X1, (IntPtr)&lzo1x_1_compress);
	m_DecompressFuncTable->Add(CompressionAlgorithm::LZO1X1, (IntPtr)&lzo1x_decompress);
	m_DecompressSafeFuncTable->Add(CompressionAlgorithm::LZO1X1, (IntPtr)&lzo1x_decompress_safe);
	m_WorkMemorySizeTable->Add(CompressionAlgorithm::LZO1X1, LZO1X_1_MEM_COMPRESS);

	m_CompressFuncTable->Add(CompressionAlgorithm::LZO1X111, (IntPtr)&lzo1x_1_11_compress);
	m_DecompressFuncTable->Add(CompressionAlgorithm::LZO1X111, (IntPtr)&lzo1x_decompress);
	m_DecompressSafeFuncTable->Add(CompressionAlgorithm::LZO1X111, (IntPtr)&lzo1x_decompress_safe);
	m_WorkMemorySizeTable->Add(CompressionAlgorithm::LZO1X111, LZO1X_1_11_MEM_COMPRESS);

	m_CompressFuncTable->Add(CompressionAlgorithm::LZO1X112, (IntPtr)&lzo1x_1_12_compress);
	m_DecompressFuncTable->Add(CompressionAlgorithm::LZO1X112, (IntPtr)&lzo1x_decompress);
	m_DecompressSafeFuncTable->Add(CompressionAlgorithm::LZO1X112, (IntPtr)&lzo1x_decompress_safe);
	m_WorkMemorySizeTable->Add(CompressionAlgorithm::LZO1X112, LZO1X_1_12_MEM_COMPRESS);

	m_CompressFuncTable->Add(CompressionAlgorithm::LZO1X115, (IntPtr)&lzo1x_1_15_compress);
	m_DecompressFuncTable->Add(CompressionAlgorithm::LZO1X115, (IntPtr)&lzo1x_decompress);
	m_DecompressSafeFuncTable->Add(CompressionAlgorithm::LZO1X115, (IntPtr)&lzo1x_decompress_safe);
	m_WorkMemorySizeTable->Add(CompressionAlgorithm::LZO1X115, LZO1X_1_15_MEM_COMPRESS);

	m_CompressFuncTable->Add(CompressionAlgorithm::LZO1X999, (IntPtr)&lzo1x_999_compress);
	m_DecompressFuncTable->Add(CompressionAlgorithm::LZO1X999, (IntPtr)&lzo1x_decompress);
	m_DecompressSafeFuncTable->Add(CompressionAlgorithm::LZO1X999, (IntPtr)&lzo1x_decompress_safe);
	m_WorkMemorySizeTable->Add(CompressionAlgorithm::LZO1X999, LZO1X_999_MEM_COMPRESS);
}

String^ LZOCompressorHelper::ResolveCompressDecompressError(int retCode)
{
	switch (retCode)
	{
	case LZO_E_ERROR:
		return "Any other error (data corrupted)";
	case LZO_E_OUT_OF_MEMORY:
		return "lzo_alloc_func_t() failure";
	case LZO_E_INPUT_OVERRUN:
		return "The decompresser requested more bytes from the compressed block than available. Your data is corrupted (or 'src_len' is too small)";
	case LZO_E_OUTPUT_OVERRUN:
		return "The decompresser requested to write more bytes to the uncompressed block than available. Either your data is corrupted, or you should increase the number of available bytes passed in the variable pointed by 'dst_len'";
	case LZO_E_LOOKBEHIND_OVERRUN:
		return "Your data is corrupted";
	case LZO_E_EOF_NOT_FOUND:
		return "No EOF code was found in the compressed block. Your data is corrupted (or 'src_len' is too small)";
	default:
		return nullptr;
	}
}
